package com.hqd.ch03.v11.spel.standard;

import com.hqd.ch03.v11.spel.EvaluationContext;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.NoSuchElementException;

/**
 * 表达式运行时状态
 */
public class ExpressionState {
    private final EvaluationContext evaluationContext;
    private final Object rootObject;
    private Deque<Object> contextObjects = new ArrayDeque<>();

    public ExpressionState(EvaluationContext context) {
        this(context, context.getRootObj());
    }

    public ExpressionState(EvaluationContext context, Object rootObject) {
        this.evaluationContext = context;
        this.rootObject = rootObject;
    }

    public EvaluationContext getEvaluationContext() {
        return evaluationContext;
    }

    /**
     * 获取栈顶元素
     *
     * @return
     */
    public Object getActiveContextObject() {
        if (CollectionUtils.isEmpty(this.contextObjects)) {
            return this.rootObject;
        }
        return this.contextObjects.element();
    }

    /**
     * 压栈
     *
     * @param obj
     */
    public void pushActiveContextObject(Object obj) {
        this.contextObjects.push(obj);
    }

    /**
     * 出栈
     *
     * @return
     */
    public Object popActiveContextObject() {
        try {
            return this.contextObjects.pop();
        } catch (NoSuchElementException ex) {
            throw new IllegalStateException("Cannot pop active context object: stack is empty");
        }
    }
}
